package com.hn.project.rqinspect.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.hn.common.enums.RoleTypeEnum;
import com.hn.common.enums.TaskTypeEnum;
import com.hn.common.exception.TaskException;
import com.hn.common.utils.OrderUtil;
import com.hn.common.utils.SecurityUtils;
import com.hn.common.utils.job.ScheduleUtils;
import com.hn.common.utils.job.SysJob;
import com.hn.doc.xyj.annotation.Api;
import com.hn.framework.web.controller.BaseController;
import com.hn.framework.web.domain.AjaxResult;
import com.hn.framework.web.page.TableDataInfo;
import com.hn.project.rqinspect.domain.database.*;
import com.hn.project.rqinspect.domain.dto.*;
import com.hn.project.rqinspect.domain.vo.GenTaskVo;
import com.hn.project.rqinspect.domain.vo.RemindVo;
import com.hn.project.rqinspect.domain.vo.TaskRecordVo;
import com.hn.project.rqinspect.service.BranchService;
import com.hn.project.rqinspect.service.SysUserService;
import com.hn.project.rqinspect.service.TaskService;
import com.hn.project.rqinspect.service.UserGroupService;
import com.hn.utils.AssertUtils;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 任务
 *
 * @author admin
 */
@Api("任务")
@RestController
@RequestMapping("task")
public class TaskController extends BaseController {

    @Autowired
    private TaskService taskService;

    @Autowired
    private UserGroupService userGroupService;

    @Autowired
    private BranchService branchService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private Scheduler scheduler;

    /**
     * 统计代办任务
     */
    @Api(value = "统计代办任务", result = CountTodoTaskDto.class)
    @PostMapping("countTodoTask")
    public AjaxResult countTodoTask() {
        Integer userId = SecurityUtils.getUserId();
        // 查询当前用户所在的分组
        List<Integer> groupIds = userGroupService.listGroupIdsByUserId(userId);
        if (groupIds == null || groupIds.isEmpty()) {
            return AjaxResult.success();
        }
        return AjaxResult.success(taskService.countTodoTask(groupIds));
    }

    /**
     * 任务记录列表
     * - 代办任务
     */
    @Api(value = "代办任务列表", result = TaskRecordDto.class)
    @GetMapping("listTodoTask")
    public TableDataInfo listTodoTask(TaskRecordVo taskRecordVo) {
        Integer userId = SecurityUtils.getUserId();
        // 查询当前用户所在的分组
        List<Integer> groupIds = userGroupService.listGroupIdsByUserId(userId);
        if (groupIds == null || groupIds.isEmpty()) {
            return getDataTable(new ArrayList<>());
        }
        List<Integer> taskIds = taskService.listTaskIdsByGroupIds(groupIds);
        if (taskIds == null || taskIds.isEmpty()) {
            return getDataTable(new ArrayList<>());
        }
        taskRecordVo.setTaskIds(taskIds);
        Integer status = taskRecordVo.getStatus();
        if (status == null) {
            taskRecordVo.setStatus(1);
        }
        taskRecordVo.setUserId(userId);
        startPage();
        return getDataTable(taskService.listTodoTask(taskRecordVo));
    }

    /**
     * 代办任务详情
     */
    @Api(value = "代办任务详情", result = TaskRecordDto.class)
    @GetMapping("getTaskRecord")
    public AjaxResult getTaskRecord(Integer pushRecordId) {
        TaskRecordDto taskRecord = taskService.getTaskRecord(pushRecordId);
        if (taskRecord != null) {
            String checkUserName = taskRecord.getCheckUserName();
            if (StrUtil.isBlank(checkUserName)) {
                Integer userId = SecurityUtils.getUserId();
                SysUser user = userService.getUserById(userId);
                taskRecord.setCheckUserName(user.getUserName());
            }
        }
        return AjaxResult.success(taskRecord);
    }

    /**
     * 领取任务
     */
    @Api(value = "领取任务")
    @GetMapping("receiveTaskRecord")
    public AjaxResult receiveTaskRecord(Integer pushRecordId) {
        return toAjax(taskService.receiveTaskRecord(pushRecordId));
    }

    /**
     * 查询任务详情
     */
    @Api(value = "任务介绍", result = Task.class)
    @GetMapping("get")
    public AjaxResult get(Integer taskId) {
        Task task = taskService.get(taskId);
        if (task != null) {
            Integer days = task.getDays();
            String triggerModeTemplate = "任一网点在被干部巡检{0}天后将开放出一个新的巡检任务,最先到达该网点的干部获得该任务。" +
                    "获得的任务需在24小时内完成,否则视为任务失败。";
            String format = MessageFormat.format(triggerModeTemplate, days);
            task.setTriggerMode(format);
        }
        return AjaxResult.success(task);
    }

    /**
     * 查询当前任务下的其他巡检人员
     */
    @Api(value = "查询当前任务下的其他巡检人员", result = CheckUserDto.class)
    @GetMapping("listCheckUsers")
    public AjaxResult listCheckUsers(Integer taskId) {
        AssertUtils.notNull("taskId", "请选择对应任务");
        Integer userId = SecurityUtils.getUserId();
        return AjaxResult.success(taskService.listCheckUsers(taskId, userId));
    }

    /**
     * 查询网点的历史巡检记录统计信息
     */
    @Api(value = "历史巡检记录统计信息", result = TaskCheckCountDto.class)
    @GetMapping("countTaskCheckRecord")
    public AjaxResult countTaskCheckRecord(Integer branchId) {
        return AjaxResult.success(taskService.countTaskCheckRecord(branchId));
    }

    /**
     * 开始巡检
     */
    @Api(value = "开始巡检")
    @PostMapping("saveTaskRecord")
    public AjaxResult saveTaskRecord(@RequestBody TaskRecord taskRecord) {
        Integer userId = SecurityUtils.getUserId();
        taskRecord.setCheckUserId(userId);
        return AjaxResult.success(taskService.saveTaskRecord(taskRecord));
    }

    /**
     * <pre>
     * 统计未检查部位
     * 您本次共完成2个部位的检查
     * 检出1个部位的不合格问题
     * </pre>
     */
    @Api(value = "提交巡检前 统计未检查部位", result = CountSubmitBeforeDto.class)
    @PostMapping("countSubmitBefore")
    public AjaxResult countSubmitBefore(@RequestBody Map<String, Integer> map) {
        Integer taskRecordId = map.get("taskRecordId");
        AssertUtils.notNull(taskRecordId, "请选择巡检记录");
        return AjaxResult.success(taskService.countSubmitBefore(taskRecordId));
    }

    /**
     * <pre>
     * 1、照片水印：巡检时上传的照片要自动被加上水印（拍摄时间、拍摄地点、拍摄人）。
     * 2、每个部位可添加0～1个好评，每个好评每次添加对1个检查点的评价。
     * 每个部位可添加0～多个差评记录，每个差评每次可添加对1个检查点的评价。
     * 剩余未评价检查点默认为合格。
     * 3、一个部位有多个检查点，对一个检查点点评价只能是好评或差评或合格之一。已被评价过的检查点在地址选项中不可选。
     * 4、当每个部位的巡检信息大于1条时，方可提交为巡检报告。否则提示“您的本次巡检尚有未巡检的部位，无法提交巡检报告。请继续巡检或左上角退出保存。“
     * </pre>
     * 提交巡检
     */
    @Api(value = "提交巡检")
    @PostMapping("submit")
    public AjaxResult submit(Integer taskRecordId) {
        return toAjax(taskService.submit(taskRecordId));
    }

    /**
     * 我的任务统计
     *
     * @param type     1=代办 2=已完成   4=草稿统计 5=查询问题统计 6=审核通过统计 7=待审核统计
     * @param roleType 1=巡检干部 2=网点负责人
     */
    @Api(value = "我的任务统计", result = CountTaskNumDto.class)
    @PostMapping("countTaskNum")
    public AjaxResult countTaskNum(Integer type, Integer roleType) {
        Integer userId = SecurityUtils.getUserId();

        AssertUtils.notNull(type, "type 必传");

        switch (type) {
            case 1:
                // 查询当前用户所在的分组
                List<Integer> groupIds = userGroupService.listGroupIdsByUserId(userId);
                if (groupIds == null || groupIds.isEmpty()) {
                    return AjaxResult.success();
                }
                return AjaxResult.success(taskService.countTodoTask(groupIds));
            case 2:
                AssertUtils.notNull(roleType, "roleType 必传");
                return AjaxResult.success(taskService.countFinishTask(userId, roleType));
            case 4:
                return AjaxResult.success(taskService.countDraftTask(userId));
            case 5:
                AssertUtils.notNull(roleType, "roleType 必传");
                if (RoleTypeEnum.BRANCH.type.equals(roleType)) {
                    return AjaxResult.success(taskService.countBranchQuesTask(userId));
                } else {
                    return AjaxResult.success(taskService.countQuesTask(userId));
                }
            case 6:
                return AjaxResult.success(taskService.countAuditSuccessTask(userId));
            case 7:
                return AjaxResult.success(taskService.countAuditTodoTask(userId));
            default:
                return AjaxResult.success();
        }
    }

    /**
     * 我的草稿列表
     */
    @Api(value = "我的草稿列表", result = DraftTaskDto.class)
    @GetMapping("listDraftTask")
    public TableDataInfo listDraftTask(Integer taskType) {
        Integer userId = SecurityUtils.getUserId();
        startPage();
        return getDataTable(taskService.listDraftTask(userId, taskType));
    }

    /**
     * 根据经纬度触发干部巡检任务
     */
    @Api(value = "根据经纬度触发干部巡检任务", result = GenTaskDto.class)
    @PostMapping("genTask")
    public AjaxResult genTask(@RequestBody GenTaskVo genTaskVo) {
        // 查询距离1km的网点
        String lng = genTaskVo.getLng();
        String lat = genTaskVo.getLat();
        if (StrUtil.isBlank(lng) || StrUtil.isBlank(lat)) {
            logger.error("请先开启定位");
            return AjaxResult.error("请先开启定位");
        }
        Integer userId = SecurityUtils.getUserId();
        return taskService.genTask(lng, lat, userId);
    }


    /**
     * 一小时后提醒
     */
    @Api(value = "一小时后提醒")
    @PostMapping("addRemind")
    public AjaxResult addRemind(@RequestBody RemindVo remindVo) throws TaskException, SchedulerException {
        Integer pushRecordId = AssertUtils.notNull(remindVo.getPushRecordId(), "请选择任务");

        Integer userId = SecurityUtils.getUserId();
        SysJob sysJob = new SysJob();
        sysJob.setConcurrent("1");
        sysJob.setInvokeTarget("rqinspectTask.sendTaskNotice(" + pushRecordId + "," + userId + ")");
        // 1个小时后提醒
        sysJob.setStartAt(DateUtil.offsetMinute(DateUtil.date(), 1));
        sysJob.setJobGroup("DEFAULT");
        sysJob.setJobId(RandomUtil.randomString(16));
        sysJob.setJobName("推送通知任务");
        sysJob.setStatus("0");
        ScheduleUtils.createScheduleJob(scheduler, sysJob);

        return AjaxResult.success();
    }

}
